package com.offcn.search.service.impl;

import com.alibaba.fastjson.JSON;
import com.offcn.search.dao.SkuEsMapper;
import com.offcn.search.pojo.SkuInfo;
import com.offcn.search.service.SkuService;
import com.offcn.sellergood.feign.ItemFeign;
import com.offcn.sellergood.pojo.Brand;
import com.offcn.sellergood.pojo.Item;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.*;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;

@Service
public class SkuServiceImpl implements SkuService {
    @Autowired
    private ItemFeign itemFeign;

    @Autowired
    private SkuEsMapper skuMapper;


    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Override
    public void importSku() {
        // 查询所有被审核通过的Item  (远程调用)
        List<Item> items = itemFeign.findByStatus("1").getData();
       // System.out.println(items);
        // 转换方式一：属性值的复制 (属性名必须一致)

        //        BeanUtils.copyProperties();

        // 转换方式二: json转换
        // 将 items 转换为 json格式，将json字符串转换为 SkuInfo
        String items_json_str = JSON.toJSONString(items);
        List<SkuInfo> skus = JSON.parseArray(items_json_str, SkuInfo.class);

        // sku中的 specMap 添加内容
        for (SkuInfo skuInfo : skus) {
            Map<String, Object> specMap = JSON.parseObject(skuInfo.getSpec(), Map.class);
            skuInfo.setSpecMap(specMap);
        }
        // 导入
       skuMapper.saveAll(skus);
    }

    @Override
    public Map search(Map<String, String> searchMap) {
        // 获取进行搜索的关键词
        String keywords = searchMap.get("keywords");
        if(StringUtils.isEmpty(keywords)){
            keywords = "手机";
        }

        // 获取分页数据
        // 当前显示 第num 页的数据
        Integer pageNum = Integer.parseInt(searchMap.get("pageNum"));
        if (pageNum == null){
            pageNum = 1;
        }
        Integer pageSize = 10;


        // 1.创建搜索构建对象
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();

        // 2.1 分页数据
        queryBuilder.withPageable(PageRequest.of(pageNum,pageSize));
        //2.2 高亮显示
        queryBuilder.withHighlightFields(new HighlightBuilder.Field("title"));
        queryBuilder.withHighlightBuilder(new HighlightBuilder().preTags("<span style=\"color:red\">").postTags("</span>"));

        // 2. 设定搜索的条件
//        queryBuilder.withQuery(QueryBuilders.matchQuery("title",keywords));
        queryBuilder.withQuery(QueryBuilders.multiMatchQuery(keywords,"title","brand","category"));

        // 分组查询 (分组字段的设定)
        queryBuilder.addAggregation(AggregationBuilders.terms("skucategory").field("category"));

        //根据品牌进行分组
        queryBuilder.addAggregation(AggregationBuilders.terms("skuBrand").field("brand"));

        //根据spec进行分组
        queryBuilder.addAggregation(AggregationBuilders.terms("skuSpec").field("spec.keyword"));

        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        //根据品牌过滤查询
        if (!StringUtils.isEmpty(searchMap.get("brand"))){
//            BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
            BoolQueryBuilder brandFilter = boolQuery.filter(QueryBuilders.matchQuery("brand", searchMap.get("brand")));
            queryBuilder.withFilter(brandFilter);
        }
        // 根据分类过滤查询
        if (!StringUtils.isEmpty(searchMap.get("category"))){
//            BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
            BoolQueryBuilder filter = boolQuery.filter(QueryBuilders.matchQuery("category", searchMap.get("category")));
            queryBuilder.withFilter(filter);
        }
        // 规格：搜索的字段  specMap.规格名.keyword
        //      提交的参数为了方便划分  spec_规格名
        if (searchMap != null) {
            for (String key : searchMap.keySet()) {
                if (key.startsWith("spec_")){  // 规格的查询  spec_网络
//                    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
                    String specName = key.substring(5);
                    BoolQueryBuilder specFilter = boolQuery.filter(QueryBuilders.termQuery("specMap." + specName + ".keyword", searchMap.get(key)));
                    queryBuilder.withFilter(specFilter);
                }
            }
        }

        // 价格过滤查询
        String price = searchMap.get("price");
        if (!StringUtils.isEmpty(price)){
            String[] prices = price.split("-");
//            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            if (!prices[1].equals("*")){
                boolQuery.filter(QueryBuilders.rangeQuery("price").lt(prices[1]));
            }
            boolQuery.filter(QueryBuilders.rangeQuery("price").gte(prices[0]));
            queryBuilder.withFilter(boolQuery);
        }

        //// 排序
        String sortField = searchMap.get("sortField");//paixuzisuan
        String sortRule = searchMap.get("sortRule"); //排序规则
        if (!StringUtils.isEmpty(sortField) && !StringUtils.isEmpty(sortRule)){
            FieldSortBuilder sortBuilder = SortBuilders.fieldSort(sortField).order(sortRule.equalsIgnoreCase("asc") ? SortOrder.ASC : SortOrder.DESC);
            queryBuilder.withSort(sortBuilder);
        }


        // 3. 构造查询对象
        NativeSearchQuery query = queryBuilder.build();
        // 4. 执行查询
        SearchHits<SkuInfo> searchHits = elasticsearchRestTemplate.search(query, SkuInfo.class);

        System.out.println(searchHits);

        // 获取分组category查询结果
        Terms skucategory = searchHits.getAggregations().get("skucategory");
        List<String> categoryList = getGroupList(skucategory);

        // 获取分组brand查询结果
        Terms skuBrand = searchHits.getAggregations().get("skuBrand");
        System.out.println(skuBrand);
        List<String> brandList = getGroupList(skuBrand);

        //获取spec分组查询结果
        Terms skuSpc = searchHits.getAggregations().get("skuSpec");
        Map<String, Set<String>> specMap = getSpecMap(skuSpc);
        System.out.println("++++++++++++++++++++++++++="+specMap);


        // 对搜索集合进行分页的封装 ，skuPage 包含分页的相关数据 总记录，总页数
        SearchPage<SkuInfo> skuPage = SearchHitSupport.searchPageFor(searchHits, query.getPageable());

        List<SearchHit<SkuInfo>> content = skuPage.getContent();

        List<SkuInfo> skuList = new ArrayList<>();
        for (SearchHit<SkuInfo> skuInfoSearchHit : content) {
            SkuInfo sku = skuInfoSearchHit.getContent();
            skuList.add(sku);
            Map<String, List<String>> highlightFields = skuInfoSearchHit.getHighlightFields();
            for (Map.Entry<String, List<String>> stringListEntry : highlightFields.entrySet()) {
                String key = stringListEntry.getKey();
                if (key.equals("title")){
                    String highLightTitle = stringListEntry.getValue().get(0);
                    skuInfoSearchHit.getContent().setTitle(highLightTitle);
                }
            }
        }
        Map<Object, Object> resultMap = new HashMap<>();
        resultMap.put("rows",skuList);
        resultMap.put("totle",skuPage.getTotalElements());
        resultMap.put("totlePages",skuPage.getTotalPages());
        resultMap.put("categoryList",categoryList);

        resultMap.put("brands",brandList);
        resultMap.put("skuSpec",specMap);
        return resultMap;
    }

    private List<String>getGroupList(Terms terms){
        List<String> groups = new ArrayList<>();
        if (terms != null){
            for (Terms.Bucket bucket : terms.getBuckets()) {
                String brand = bucket.getKeyAsString();
                groups.add(brand);
            }
        }
        return groups;
    }
    private Map<String, Set<String>>getSpecMap(Terms terms){
        ArrayList<String> specList = new ArrayList<>();
        if (terms != null) {
            for (Terms.Bucket bucket : terms.getBuckets()){
                specList.add(bucket.getKeyAsString());
            }
        }
        //定义返回值类型的对象
        Map<String, Set<String>> specResult = new HashMap<>();
        for (String specStr : specList) {
            Map<String,String> map = JSON.parseObject(specStr, Map.class);
            for (Map.Entry<String, String> entry : map.entrySet()) {
                String key = entry.getKey();  // 网络
                String value = entry.getValue(); // 移动4G  , 移动3G
                Set<String> specValues = specResult.get(key);    //  网络  ==》 Set{移动4G，移动3G}
                if (specValues == null) {
                    specValues = new HashSet<>(); // Set
                }
                specValues.add(value);
                specResult.put(key,specValues);
            }
        }
        return specResult;
    }
}

